package controllers.monorent;

import controllers.RestAuth;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import play.mvc.*;

import java.util.*;

import javax.imageio.ImageIO;
import models.User;
import models.monorent.*;

import play.db.jpa.Blob;
import play.db.jpa.GenericModel;
import play.libs.MimeTypes;

public class RentInfoRest extends Controller {

	static public void getAllRentInfo() {
		List<RentInfo> allRentInfo = RentInfo.findAll();
		renderJSON(allRentInfo, new RentInfoSerializer());
	}

	static public void getRentInfo(Long id) {
		RentInfo ri = RentInfo.findById(id);
		if(ri != null) {
			renderJSON(ri, new RentInfoSerializer());
		} else {
			renderJSON("invalid id");
		}
	}
	
	static public void createRentInfo() {
        
        long userid = RestAuth.auth(request);
        if(userid == 0) {
            renderJSON("auth failed");
            return;
        }
        
        String tmp;
		String name = params.get("name");
		String location = params.get("loc");
        double lat = Double.parseDouble((tmp = params.get("lat")) == null ? "0": tmp);
        double lng = Double.parseDouble((tmp = params.get("lng")) == null ? "0": tmp);
        String description = params.get("desc");
        int price = Integer.parseInt((tmp = params.get("price")) == null ? "0": tmp);
        int bedroom = Integer.parseInt((tmp = params.get("bed")) == null ? "0": tmp);
        int bathroom = Integer.parseInt((tmp = params.get("bath")) == null ? "0": tmp);
        int petAllowed = Integer.parseInt((tmp = params.get("pet")) == null ? "0": tmp);
        int furnitured = Integer.parseInt((tmp = params.get("fur")) == null ? "0": tmp);
        
        RentInfo ri = new RentInfo(userid, name, location, lat, lng, description, price, bedroom, bathroom, petAllowed, furnitured).save();
        renderJSON(ri, new RentInfoSerializer());
	}
	
	static public void updateRentInfo(Long id) {
		
        long userid = RestAuth.auth(request);
        if(userid == 0) {
            renderJSON("auth failed");
            return;
        }
        
		RentInfo ri = RentInfo.findById(id);
		if(ri == null) {
            renderJSON("invalid id");
            return;
        }
        if(ri.owner.id != userid) {
            renderJSON("auth failed");
            return;
        }
		
        // update parameters
        String param;
        if((param = params.get("name")) != null) ri.name = param; 
        if((param = params.get("loc")) != null) ri.location = param; 
        if((param = params.get("lat")) != null) ri.lat = Double.parseDouble(param); 
        if((param = params.get("lng")) != null) ri.lng = Double.parseDouble(param); 
        if((param = params.get("desc")) != null) ri.description = param; 
        if((param = params.get("price")) != null) ri.price = Integer.parseInt(param); 
        if((param = params.get("bed")) != null) ri.bedroomCount = Integer.parseInt(param); 
        if((param = params.get("bath")) != null) ri.bathroomCount = Integer.parseInt(param); 
        if((param = params.get("pet")) != null) ri.petsAllowed = Integer.parseInt(param); 
        if((param = params.get("fur")) != null) ri.furnitured = Integer.parseInt(param); 

        ri.save();
        renderJSON(ri, new RentInfoSerializer());
        return;
	}
	
	static public void deleteRentInfo(Long id) {
        long userid = RestAuth.auth(request);
        if(userid == 0) {
            renderJSON("auth failed");
            return;
        }
        
		RentInfo ri = RentInfo.findById(id);
		if(ri == null) {
            renderJSON("invalid id");
            return;
        }
        if(ri.owner.id != userid) {
            renderJSON("auth failed");
            return;
        }
		ri.delete();
		renderJSON("success");
	}
    
    static public void getRentInfoByOwner(Long uid) {
        List<RentInfo> ris = RentInfo.find("select r from RentInfo r where r.owner.id=? order by createDate desc", uid).fetch();
        renderJSON(ris, new RentInfoSerializer());
    }
    
    static public void getRentInfoImage(Long id, int iid) {
        RentInfo ri = RentInfo.findById(id);
        if(ri == null) {
            renderJSON("invalid id");
            return;
        }
        if(iid >= ri.images.size()) {
            renderJSON("");
            return;
        }
        RentInfoImage rii = ri.images.get(iid);
        
        response.setContentTypeIfNotSet(rii.image.type());
		renderBinary(rii.image.get());
    }
    
    static public void createRentInfoImage(Long id) {
        long userid = RestAuth.auth(request);
        if(userid == 0) {
            renderJSON("auth failed");
            return;
        }
        
		RentInfo ri = RentInfo.findById(id);
		if(ri == null) {
            renderJSON("invalid id");
            return;
        }
        if(ri.owner.id != userid) {
            renderJSON("auth failed");
            return;
        }
        
        String filename = request.headers.get("x-file-name").value();
        if(filename == null) {
            filename = "image.png";
        }
        
        RentInfoImage newRIImage = new RentInfoImage();
        newRIImage.image = new Blob();
        newRIImage.image.set(request.body, MimeTypes.getContentType(filename));	
        if(ri.images.isEmpty()) {
            newRIImage.iorder = 100;
        } else {
            newRIImage.iorder = ri.images.get(ri.images.size() - 1).iorder + 100;
        }
        newRIImage.rentinfo = ri;
        ri.images.add(newRIImage);
        
        newRIImage.save();
        ri.save();
        renderJSON("{\"id\":" + ri.images.get(ri.images.size() - 1).id + 
                " \"rid\":" + ri.id + 
                " \"order\":" + newRIImage.iorder + "}");
    }
    
    static public void updateRentInfoImage(Long id, int idx) {
        
        long userid = RestAuth.auth(request);
        if(userid == 0) {
            renderJSON("auth failed");
            return;
        }
        
		RentInfo ri = RentInfo.findById(id);
		if(ri == null) {
            renderJSON("invalid id");
            return;
        }
        if(ri.owner.id != userid) {
            renderJSON("auth failed");
            return;
        }
        
        if(ri.images.size() <= idx) {
            renderJSON("invalid index");
            return;
        }
        
        String filename = request.headers.get("x-file-name").value();
        if(filename == null) {
            filename = "image.png";
        }

        if(ri.images.get(idx).image.exists()) {
            ri.images.get(idx).image.getFile().delete();
        }
        ri.images.get(idx).image = new Blob();
        ri.images.get(idx).image.set(request.body, MimeTypes.getContentType(filename));
        
        ri.save();
        renderJSON("{\"id\":" + ri.images.get(ri.images.size() - 1).id + 
            " \"rid\":" + ri.id + 
            " \"order\":" + ri.images.get(idx).iorder + "}");
        return;     
    }
    
    static public void deleteRentInfoImage(Long id, int idx) {
        long userid = RestAuth.auth(request);
        if(userid == 0) {
            renderJSON("auth failed");
            return;
        }
        
		RentInfo ri = RentInfo.findById(id);
		if(ri == null) {
            renderJSON("invalid id");
            return;
        }
        if(ri.owner.id != userid) {
            renderJSON("auth failed");
            return;
        }

        if(ri.images.get(idx).image.exists()) {
            ri.images.get(idx).image.getFile().delete();
        }
        ri.images.get(idx).delete();
        ri.images.remove(idx);
        ri.save();
        renderJSON("success");
    }
}
